
#ifndef __dmStringTuples_h
#define __dmStringTuples_h

#include "dmAbstractTuples.h"
#include "dmIdList.h"
#include <string>       // For the superclass.

class dmStringTuplesLookup;

class dmStdString : public std::string
{
public:
	typedef std::string StdString;
	typedef StdString::value_type             value_type;
	typedef StdString::pointer                pointer;
	typedef StdString::reference              reference;
	typedef StdString::const_reference        const_reference;
	typedef StdString::size_type              size_type;
	typedef StdString::difference_type        difference_type;
	typedef StdString::iterator               iterator;
	typedef StdString::const_iterator         const_iterator;
	typedef StdString::reverse_iterator       reverse_iterator;
	typedef StdString::const_reverse_iterator const_reverse_iterator;

	dmStdString(): StdString() {}
	dmStdString(const value_type* s): StdString(s) {}
	dmStdString(const value_type* s, size_type n): StdString(s, n) {}
	dmStdString(const StdString& s, size_type pos=0, size_type n=npos):
		StdString(s, pos, n) {}

	operator const char *() { return this->c_str(); }
};

class DMDB_BASE_API dmStringTuples : public dmAbstractTuples
{
public:
  static dmStringTuples* New();
  dmTypeMacro(dmStringTuples,dmAbstractTuples);

  // Description:
  // Get the data type.
  int GetDataType()
    { return DM_STRING; }

  int IsNumeric() { return 0; }

  // Description:
  // Release storage and reset array to initial state.
  void Initialize();

  // Description:
  int GetDataTypeSize();

  // Description:
  void Squeeze() { this->ResizeAndExtend (this->MaxId+1); }

  // Description:
  int Resize(dmIdType numTuples);

  // Description:
  virtual void SetTuple(dmIdType i, dmIdType j, dmAbstractTuples* source);

  // Description:
  virtual void InsertTuple(dmIdType i, dmIdType j, dmAbstractTuples* source);

  // Description:
  virtual void InsertTuples(dmIdList *dstIds, dmIdList *srcIds,
                            dmAbstractTuples *source);

  // Description:
  virtual dmIdType InsertNextTuple(dmIdType j, dmAbstractTuples* source);

  // Description:
  virtual void InterpolateTuple(dmIdType i, dmIdList *ptIndices,
    dmAbstractTuples* source,  double* weights);

  // Description
  virtual void InterpolateTuple(dmIdType i,
    dmIdType id1, dmAbstractTuples* source1,
    dmIdType id2, dmAbstractTuples* source2, double t);

  // Description:
  virtual void GetTuples(dmIdList *ptIds, dmAbstractTuples *output);

  // Description:
  virtual void GetTuples(dmIdType p1, dmIdType p2, dmAbstractTuples *output);

  // Description:
  int Allocate( dmIdType sz, dmIdType ext=1000 );

  // Description:
  dmStdString &GetValue(dmIdType id);

//BTX
  // Description:
  void SetValue(dmIdType id, dmStdString value)
    { this->Array[id] = value; this->DataChanged(); }
//ETX
  void SetValue(dmIdType id, const char *value);

  // Description:
  virtual void SetNumberOfTuples(dmIdType number)
    { this->SetNumberOfValues(this->NumberOfComponents* number); }

  // Description:
  void SetNumberOfValues(dmIdType number);

  dmIdType GetNumberOfValues() { return this->MaxId + 1; }

  int GetNumberOfElementComponents() { return 0; }
  int GetElementComponentSize() { return static_cast<int>(sizeof(dmStdString::value_type)); }

//BTX
  // Description:
  // Insert data at a specified position in the array.
  void InsertValue(dmIdType id, dmStdString f);
//ETX
  void InsertValue(dmIdType id, const char *val);


//BTX
  // Description:
  // Insert data at the end of the array. Return its location in the array.
  dmIdType InsertNextValue(dmStdString f);
//ETX
  dmIdType InsertNextValue(const char *f);

//BTX
  // Description:
  dmStdString* WritePointer(dmIdType id, dmIdType number);
//ETX

//BTX
  // Description:
  dmStdString* GetPointer(dmIdType id) { return this->Array + id; }
  void* GetVoidPointer(dmIdType id) { return this->GetPointer(id); }
//ETX

  // Description:
  // Deep copy of another string array.  Will complain and change nothing
  // if the array passed in is not a dmStringTuples.
  void DeepCopy( dmAbstractTuples* aa );


//BTX
  // Description:
  void SetArray(dmStdString* array, dmIdType size, int save);
  virtual void SetVoidArray(void* array, dmIdType size, int save)
    { this->SetArray(static_cast<dmStdString*>(array), size, save); }
//ETX

  // Description:
  unsigned long GetActualMemorySize();

  // Description:
  virtual dmIdType GetDataSize();

//BTX
  dmIdType LookupValue(dmStdString value);
  void LookupValue(dmStdString value, dmIdList* ids);
//ETX
  dmIdType LookupValue(const char* value);
  void LookupValue(const char* value, dmIdList* ids);

  // Description:
  virtual void DataChanged();

  // Description:
  virtual void DataElementChanged(dmIdType id);

  // Description:
  virtual void ClearLookup();

protected:
  dmStringTuples();
  ~dmStringTuples();

  dmStdString* Array;   // pointer to data
  dmStdString* ResizeAndExtend(dmIdType sz);  // function to resize data

  int SaveUserArray;

private:
  dmStringTuples(const dmStringTuples&);  // Not implemented.
  void operator=(const dmStringTuples&);  // Not implemented.

  //BTX
  dmStringTuplesLookup* Lookup;
  void UpdateLookup();
  //ETX
};

#endif
